"""
数据库连接管理

提供异步数据库连接管理功能，包括：
- 数据库连接池管理
- 会话工厂管理
- 依赖注入支持
"""

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine, async_sessionmaker
from configs import mysql as mysql_config

Base = declarative_base()

class DatabaseManager:
    """
    数据库管理器
    
    管理数据库连接池和会话工厂
    """
    
    def __init__(self):
        """
        初始化数据库管理器
        """
        self.engine = None
        self.session_factory = None
        self.url = None
        self._initialize_url()
        
    def _initialize_url(self):
        """
        初始化数据库 URL
        
        根据配置文件生成数据库连接URL
        """
        self.url = f"mysql+asyncmy://{mysql_config.user}:{mysql_config.password}@{mysql_config.host}:{mysql_config.port}/{mysql_config.db}"
        
    async def init_db(self):
        """
        初始化数据库连接
        
        创建异步引擎和会话工厂
        """
        if not self.url:
            self._initialize_url()
            
        self.engine = create_async_engine(
            self.url,
            pool_size=mysql_config.pool_size,
            max_overflow=mysql_config.max_overflow,
            pool_recycle=mysql_config.pool_recycle,
            echo=False
        )
        
        self.session_factory = async_sessionmaker(
            self.engine,
            class_=AsyncSession,
            expire_on_commit=False
        )
        
    async def close_db(self):
        """
        关闭数据库连接
        
        释放数据库引擎资源
        """
        if self.engine:
            await self.engine.dispose()
            
    async def get_session(self) -> AsyncSession:
        """
        获取数据库会话
        
        Returns:
            AsyncSession: 数据库会话
        """
        if not self.session_factory:
            await self.init_db()
        return self.session_factory()

db_manager = DatabaseManager()

async def get_db():
    """
    依赖注入：获取数据库会话
    
    为FastAPI提供数据库会话依赖注入
    
    Yields:
        AsyncSession: 数据库会话
    """
    session = await db_manager.get_session()
    try:
        yield session
        await session.commit()
    except Exception:
        await session.rollback()
        raise
    finally:
        await session.close()
